package Data_Flow;

import Data_Structure.DataImplement.MealAndPrice;
import Data_Structure.DataType.CreditCardAccount;
import Data_Structure.DataType.MyFlight;
import Data_Structure.DataType.TargetFlight;
import Data_Structure.DataType.Traveller;
import GUI_Data.FlightSeatPanel.SeatButton;
import lombok.Data;

import java.io.IOException;
import java.util.HashMap;
import java.util.Objects;

/**
 * Dynamic method for GUI layer to change data of users or flights
 * @author Xin Wang
 * @since 4/17 2022
 * @version 3.0
 */
@Data
public class DataOperator {
    private boolean ifSuccess=false;
    private String bookingNumber;
    private String PersonID;
    private Traveller traveller;
    private MyFlight myFlight;
    private TargetFlight targetFlight;
    private CreditCardAccount creditCardAccount;
    private HashMap<String, MyFlight> PersonFlightList;
    private int readCount = 0;

    /**
     * Constructor.
     * Construct DataOperator by bookingNumber.
     */
    public DataOperator(String bookingNumber){
        this.bookingNumber=bookingNumber;
        try{
            this.traveller=DataExplorer.readTraveller_bookingNumber(getBookingNumber());
            this.myFlight =DataExplorer.readAndSetMyFlight(getBookingNumber());
            readCount=1;
            if(traveller!=null && myFlight!=null ){
                this.targetFlight=DataExplorer.readTargetFlight(myFlight.getMyFlightID());
                this.creditCardAccount=DataExplorer.readCreditCardAccount(traveller.getPersonID());
                if (targetFlight!=null && creditCardAccount!=null)
                    this.ifSuccess=true;
            }
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * Constructor.
     * Construct GetData by PersonID
     */
    public DataOperator(String PersonID,String SurName){
        this.PersonID=PersonID;
        try{
            this.traveller=DataExplorer.readTraveller_PersonID(getPersonID());
            if(traveller!=null && Objects.equals(traveller.getSurname(), SurName)){
                this.creditCardAccount=DataExplorer.readCreditCardAccount(traveller.getPersonID());
                this.PersonFlightList = traveller.getFlight();
                if(creditCardAccount!=null && PersonFlightList!=null) {
                    ifSuccess = true;
                }
            }

        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * User need to choose which fight it want to operate if it booked more than one flight.
     * @param FlightNumber of the flight it wants to operate.
     */
    public void ChooseFlightByFlightID(String FlightNumber){
        this.ifSuccess=false;
        try{
            this.bookingNumber = PersonFlightList.get(FlightNumber).getMyBookingNumber();
            this.myFlight=DataExplorer.readAndSetMyFlight(getBookingNumber());
            this.traveller=DataExplorer.readTraveller_bookingNumber(getBookingNumber());
            readCount=1;
            if(myFlight!=null ){
                this.targetFlight=DataExplorer.readTargetFlight(myFlight.getMyFlightID());
                if (targetFlight!=null)
                    this.ifSuccess=true;
            }

        }catch (Exception e) {
            e.printStackTrace();
        }

    }



    /**
     *Choose seat, and return a boolean value. true means success, false means fail.
     * @return a boolean value
     */
    public boolean chooseSeat(SeatButton seatButton) {
        boolean i=false;
        try {
            if(readCount==0){
                this.myFlight =DataExplorer.readAndSetMyFlight(getBookingNumber());
                readCount=1;
            }

            i= targetFlight.bookSeat(seatButton.getSeatClass(), seatButton.getSeatPosition());
            myFlight.setMySeatClass(seatButton.getSeatClass());
            myFlight.setMySeatPosition(seatButton.getSeatPosition());
            myFlight.setMySeatPrice(seatButton.getSeatPrice());
            DataExplorer.saveTargetFlight(targetFlight);
            DataExplorer.saveMyFlight(myFlight);
            readCount=0;
            DataExplorer.saveTraveller(traveller);
            System.out.println("ChooseSeatSuccess!");
        }catch (Exception e) {
            e.printStackTrace();
        }
        return i;
    }

    public void chooseMeal(MealAndPrice.Meals meals, Integer mealNumber){
        try{
            if(readCount==0){
                this.myFlight =DataExplorer.readAndSetMyFlight(getBookingNumber());
                readCount=1;
            }
            myFlight.getMeals().put(meals,mealNumber);
            DataExplorer.saveTargetFlight(targetFlight);
            DataExplorer.saveMyFlight(myFlight);
            readCount=0;
            DataExplorer.saveTraveller(traveller);
        }catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * pay
     * @param amount money need to pay.
     * @return true for success, false for fail.
     */
    public boolean withDraw(double amount){
        try {
            boolean ifSuccess = creditCardAccount.withdraw(amount);
            DataExplorer.saveCreditCardAccount(creditCardAccount);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ifSuccess;
    }
}

